#include "ThreadPool.h"

/**
 * ThreadPool implementation
 */


/**
 * @param threadNum
 * @param queSize
 */
ThreadPool::ThreadPool(size_t threadNum, size_t queSize) 
: _threadNum(threadNum)
, _threads()
, _queSize(queSize)
, _taskQueue(queSize)
, _isExit(false)
{}

ThreadPool::~ThreadPool() {}

/**
 * @return void
 */
void ThreadPool::start() {
    for(size_t i=0; i<_threadNum; ++i){
        _threads.emplace_back(&ThreadPool::doTask, this);
    }
    return;
}

/**
 * @return void
 */
void ThreadPool::stop() {
    // 1、等待队列中所有任务处理结束
    while(!_taskQueue.empty()){
        sleep(1);  // 让权等待
    }

    // 2、设置结束标志生效
    _isExit = true;
    #if DEBUG
    cout << "ThreadPool::_isExit is true." << endl;
    #endif

    // 3、唤醒所有被阻塞的子线程
    _taskQueue.wakeup();

    // 4、等待各子线程退出
    for(auto & th : _threads){  // 记得使用引用，避免thread对象的拷贝
        cout << "thread " << th.get_id() << " exit." << endl;
        th.join();
    }

    return;
}

/**
 * @param pt为右值
 * @return void
 */
void ThreadPool::addTask(ElemType && pt) {
    _taskQueue.push(std::move(pt));
    return;
}

/**
 * @brief 内部接口：子线程获取一个队列中的任务
 * @return ElemType
 */
ElemType ThreadPool::getTask() {
    return _taskQueue.pop();
}

/**
 * @brief 子线程入口函数
 * @return void
 */
void ThreadPool::doTask() {
    while(!_isExit){
        ElemType pTask = getTask();
        if(pTask){ // 只处理非空对象
            pTask();  // 调用函数对象
        }
    }
    return;
}